package com.yuanfengPlus.basicInfoManage.loginAndAuthentication.service.impl;

import com.yuanfengPlus.basicInfoManage.loginAndAuthentication.Vo.BlogUserLoginVo;
import com.yuanfengPlus.basicInfoManage.loginAndAuthentication.Vo.UserInfoVo;
import com.yuanfengPlus.basicInfoManage.loginAndAuthentication.dao.UserMapper;
import com.yuanfengPlus.basicInfoManage.loginAndAuthentication.model.LoginUser;
import com.yuanfengPlus.basicInfoManage.loginAndAuthentication.model.User;
import com.yuanfengPlus.basicInfoManage.loginAndAuthentication.service.BlogLoginService;
import com.yuanfengPlus.basicInfoManage.loginAndAuthentication.utils.BeanCopyUtils;
import com.yuanfengPlus.utils.JwtUtil;
import com.yuanfengPlus.utils.PasswordUtil;
import com.yuanfengPlus.utils.RedisCache;
import com.yuanfengPlus.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;

@Service
public class BlogLoginServiceImpl implements BlogLoginService {
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private RedisCache redisCache;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;


    /**
     * blog登录
     * @param user
     * @return
     */
    public Result login(User user) {
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        //判断是否认证通过
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("用户名或密码错误!");
        }
        //获取userId,生成token
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        Long userId = loginUser.getUser().getId();
        String jwt = JwtUtil.createJWT(userId.toString());
        //存放一个用户ID到用户浏览器的localStorage
//        localStorage.setItem("userId",userId.toString());
        //把用户信息存入redis
        redisCache.setCacheObject("bloglogin:" + userId,loginUser);
        //把token通过同样的方式存入redis
        redisCache.setCacheObject("bloglogin:" + userId+"token",jwt);
        //把token和userInfo封装，返回
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(loginUser.getUser(), UserInfoVo.class);
        BlogUserLoginVo blogUserLoginVo = new BlogUserLoginVo(jwt,userInfoVo);

        return Result.success(blogUserLoginVo);
    }

    @Override
    public Result addUser(User user) {
        if (user.getUsername() == null || user.getPassword() == null) {
            return Result.failure(400, "用户名或密码不能为空");
        } else if (user.getUsername().length() < 4 || user.getPassword().length() < 6) {
            return Result.failure(400, "用户名或密码长度不符合要求");
        } else {
            User user1 = userMapper.selectUserByUsername(user.getUsername());
            if (user1 != null) {
                return Result.failure(400, "用户名已存在");
            } else {
                String encryptedPassword = passwordEncoder.encode(user.getPassword());
                user.setPassword(encryptedPassword);
                int i = userMapper.addUser(user);
                if (i > 0) {
                    return Result.success("注册成功");
                } else {
                    return Result.failure(400, "注册失败");
                }
            }
        }
    }

    @Override
    public Result logout(String userID) {
        // 从 Redis 中获取 LoginUser 对象
        Object userObject = redisCache.getCacheObject("bloglogin:" + userID);
        Object tokenObject = redisCache.getCacheObject("bloglogin:" + userID + "token");

        if (userObject != null && tokenObject != null) {
            // 如果 Redis 中存储的是 LoginUser 对象，应该进行适当的类型转换
            if (userObject instanceof LoginUser && tokenObject instanceof String) {
                LoginUser loginUser = (LoginUser) userObject;
                String userToken = (String) tokenObject;

                // 删除 Redis 中的记录
                redisCache.deleteObject("bloglogin:" + userID);
                redisCache.deleteObject("bloglogin:" + userID + "token");

                return Result.success("登出成功");
            } else {
                // 如果 Redis 中存储的类型不匹配，需要进一步处理或抛出异常
                return Result.failure(400, "Redis 中存储的数据类型不匹配");
            }
        } else {
            return Result.failure(400, "用户不存在或已登出，请重新登录");
        }
    }

    @Override
//查询当前用户登录信息接口
    public Result getUserInfo(String userID) {
        // 从 Redis 中获取 LoginUser 对象
        Object userObject = redisCache.getCacheObject("bloglogin:" + userID);
        Object tokenObject = redisCache.getCacheObject("bloglogin:" + userID + "token");

        if (userObject != null && tokenObject != null) {
            // 如果 Redis 中存储的是 LoginUser 对象，应该进行适当的类型转换
            if (userObject instanceof LoginUser && tokenObject instanceof String) {
                LoginUser loginUser = (LoginUser) userObject;
                String userToken = (String) tokenObject;

                // 封装用户信息和 token 返回给前端
                UserInfoVo userInfoVo = BeanCopyUtils.copyBean(loginUser.getUser(), UserInfoVo.class);
                BlogUserLoginVo blogUserLoginVo = new BlogUserLoginVo(userToken, userInfoVo);

                return Result.success(blogUserLoginVo);
            } else {
                // 如果 Redis 中存储的类型不匹配，需要进一步处理或抛出异常
                return Result.failure(400, "Redis 中存储的数据类型不匹配");
            }
        } else {
            return Result.failure(400, "用户不存在或已登出，请重新登录");
        }
    }


}